

<template>
  <!-- 此组件暂时为无用组件 -->
  <div class="formLine">
    <div class="formLineTitle">
      <span class="titlecontent">Code</span>
      <div v-show="!iscorrect && state != null" class="formtips flex">
        <img v-lazy="require('@/assets/img/icon/error.svg')" alt="" />
        {{ tips }}
      </div>

      <div v-show="iscorrect" class="formtips flex">
        <img v-lazy="require('@/assets/img/icon/correct.svg')" alt="" />
      </div>
    </div>
    <div class="formLineContent">
      <input
        ref="input"
        autocomplete="off"
        :class="{ 'input-error': errorclass }"
        :type="type"
        :placeholder="placeholder"
        v-model="value"
      />
    </div>
  </div>
</template>

<script>
export default {
  name: "myinput",
  data() {
    return {
      //empty,error,correct
      state: null,
      tips: "",
      errorclass: false,
      value: "",
    };
  },
  props: {
    isrequired: {
      type: Boolean,
      default: true,
    },
    maxlength: {
      type: Number,
      default: 30,
      validator: (value) => {
        if (value < 1) {
          console.error("the maxlength must be greater than 1");
        } else {
          return value;
        }
      },
    },
    minlength: {
      type: Number,
      default: function () {
        return this.isrequired ? 1 : 0;
      },
    },
    emptyinfo: {
      type: String,
      default: "Please input",
    },
    errorinfo: {
      type: String,
      default: "Please input correct info",
    },
    type: {
      type: String,
      default: "text",
      validator: (value) => {
        let typearr = ["text", "password"];
        if (typearr.indexOf(value) != -1) {
          return value;
        } else {
          console.error("请输入正确类型!");
        }
      },
    },
    limit: {
      //default:nolimit,number,english or your RegEX
      type: String,
      default: "nolimit",
    },
    placeholder: {
      type: String,
      default: "Input...",
    },
    rule: {
      //default:none,password,email,telephone,time or your RegEx
      type: String,
      default: "none",
    },
  },
  mounted() {
    this.BindEvent();
  },
  methods: {
    validator() {
      let context = this;

      function none() {
        switch (context.isrequired) {
          case true:
            if (context.value.length >= context.minlength) {
              context.state = "correct";
              context.tips = "";
              return context.value;
            } else {
              context.state = "error";
              context.tips = context.errorinfo;
              return false;
            }
          case false:
            if (context.value != "") {
              if (context.value.length >= context.minlength) {
                context.state = "correct";
                context.tips = "";
                return context.value;
              } else {
                context.state = "error";
                context.tips = context.errorinfo;
                return false;
              }
            } else {
              return true;
            }
        }
      }

      function telephone() {
        const patt =
          /^(13[0-9]|14[5|7]|15[0|1|2|3|4|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$/g;

        switch (context.isrequired) {
          case true:
            if (
              context.value.length >= context.minlength &&
              patt.test(context.value)
            ) {
              context.state = "correct";
              context.tips = "";
              return context.value;
            } else {
              context.state = "error";
              context.tips = context.errorinfo;
              return false;
            }
          case false:
            if (context.value != "") {
              if (patt.test(context.value)) {
                context.state = "correct";
                context.tips = "";
                return context.value;
              } else {
                context.state = "error";
                context.tips = context.errorinfo;
                return false;
              }
            } else {
              return true;
            }
        }
      }

      function email() {
        const patt = /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/g;

        switch (context.isrequired) {
          case true:
            if (
              context.value.length >= context.minlength &&
              patt.test(context.value)
            ) {
              context.state = "correct";
              context.tips = "";
              return context.value;
            } else {
              context.state = "error";
              context.tips = context.errorinfo;
              return false;
            }
          case false:
            if (context.value != "") {
              if (patt.test(context.value)) {
                context.state = "correct";
                context.tips = "";
                return context.value;
              } else {
                context.state = "error";
                context.tips = context.errorinfo;
                return false;
              }
            } else {
              return true;
            }
        }
      }

      function password() {
        const patt = /^[a-zA-Z]\w{5,17}$/g;

        switch (context.isrequired) {
          case true:
            if (
              context.value.length >= context.minlength &&
              patt.test(context.value)
            ) {
              context.state = "correct";
              context.tips = "";
              return context.value;
            } else {
              context.state = "error";
              context.tips = context.errorinfo;
              return false;
            }
          case false:
            if (context.value != "") {
              if (patt.test(context.value)) {
                context.state = "correct";
                context.tips = "";
                return context.value;
              } else {
                context.state = "error";
                context.tips = context.errorinfo;
                return false;
              }
            } else {
              return true;
            }
        }
      }

      function time() {
        const patt = /^\d{4}-\d{1,2}-\d{1,2} \d{1,2}:\d{1,2}/g;

        switch (context.isrequired) {
          case true:
            if (
              context.value.length >= context.minlength &&
              patt.test(context.value)
            ) {
              context.state = "correct";
              context.tips = "";
              return context.value;
            } else {
              context.state = "error";
              context.tips = context.errorinfo;
              return false;
            }
          case false:
            if (context.value != "") {
              if (patt.test(context.value)) {
                context.state = "correct";
                context.tips = "";
                return context.value;
              } else {
                context.state = "error";
                context.tips = context.errorinfo;
                return false;
              }
            } else {
              return true;
            }
        }
      }

      function custom(rule) {
        const patt =rule;

        switch (context.isrequired) {
          case true:
            if (
              context.value.length >= context.minlength &&
              patt.test(context.value)
            ) {
              context.state = "correct";
              context.tips = "";
              return context.value;
            } else {
              context.state = "error";
              context.tips = context.errorinfo;
              return false;
            }
          case false:
            if (context.value != "") {
              if (patt.test(context.value)) {
                context.state = "correct";
                context.tips = "";
                return context.value;
              } else {
                context.state = "error";
                context.tips = context.errorinfo;
                return false;
              }
            } else {
              return true;
            }
        }
      }

      const rulearr = new Map([
        ["none", none],
        ["telephone", telephone],
        ["email", email],
        ["password", password],
        ["time", time],
        ["custom", custom],
      ]);

      //如果为必填，错误会返回false，正确会返回value值；如果不是必填，为空的情况会返回true，不为空的情况和上文一样。
      async function getresult() {
        if (context.rule != "" && !rulearr.has(context.rule)) {
          let validator=rulearr.get("custom");
          let result=await validator(context.rule);
          return result;
        } else {
          let validator = rulearr.get(context.rule || "none");
          let result = await validator();
          return result;
        }
      }

      return getresult();
    },
    BindEvent() {
      this.$refs.input.addEventListener("input", () => {
        this.validator();
      });
    },
  },

  computed: {
    whatlimit(regex) {
      const limits = new Map([
        ["nolimit", null],
        ["number", /^[0-9]*$/g],
        ["english", /^[A-Za-z]+$/g],
        ["numberenglish", /^[A-Za-z0-9]+$/g],
      ]);

      return (regex) => {
        return limits.has(regex) ? limits.get(regex) : regex;
      };
    },
    iscorrect() {
      if (this.state != null) {
        return this.state == "correct" ? true : false;
      }
    },
  },
  watch: {
    value: {
      deep: false,
      immediate: false,
      handler: function (newValue) {
        this.value = newValue.replace(this.whatlimit, "");
        if (newValue.length > this.maxlength) {
          this.value = this.value.slice(0, this.maxlength);
        }
      },
    },
  },
};
</script>

<style lang="scss" scoped>
.formLine {
  width: 95%;
  padding-left: 2.5%;
  padding-right: 2.5%;
  margin-bottom: 10px;
  position: relative;
}
.formLineTitle {
  text-align: right;
  color: $color-normal-blue;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  margin-bottom: 5px;
  font-weight: bold;
  font-size: 1rem;
  letter-spacing: 0px;
  font-family: "agency fb";
}
.formLineContent {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  margin-right: 15px;
}
input,
textarea {
  width: 98%;
  padding-left: 2%;
  outline: none;
  border: none;
  height: 25px;
  border-radius: 3px;
  transition: all 0.3s ease;
  font-size: 0.7rem;
  border: 2px solid rgba(0, 0, 0, 0);
  box-shadow: 0 0 0 rgba(0, 0, 0, 0);
}

.input-error {
}
textarea {
  padding-top: 10px;
  font-family: "Alliance No.1", -apple-system, BlinkMacSystemFont, "Segoe UI",
    Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji",
    "Segoe UI Symbol";
  font-feature-settings: "ss02" on, "ss01" on;
  line-height: 1.1rem;
  list-style: none;
}
input:focus {
  box-shadow: 0px 0px 5px white;
  background-color: rgb(232, 240, 254) !important;
}
textarea:focus {
  box-shadow: 0px 0px 5px white;
  background-color: rgb(232, 240, 254) !important;
}
.content {
  height: 180px;
}

button svg {
  width: 16px;
  height: 16px;
}
.formtips {
  margin-left: 20px;
  color: red;
  font-family: Arial, Helvetica, sans-serif;
  font-size: 0.8rem;
  z-index: 1;
}
.formtips img {
  width: 20px;
  margin-right: 5px;
}
.titlecontent {
  width: 60px;
  text-align: left;
}
</style>